/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#include "./vStringConverter.h"
#include "../Framework/Graphics/vColor.h"
#include "./vStringTokenizer.h"

namespace Vendetta {
	vStringConverter::vStringConverter() {
	}

	vStringConverter::~vStringConverter() {
	}

	vString vStringConverter::ToString(vReal rVal, vUShort usPrecision, vUShort usWidth, vChar cFill, 
									   std::ios::fmtflags flags) {
		vStringStream stream;

		stream.precision(usPrecision);
		stream.width(usWidth);
		stream.fill(cFill);

		if (flags) {
			stream.setf(flags);
		}
		stream<<rVal;

		return vString(stream.str());
	}

	vString vStringConverter::ToString(vInt iVal, vUShort usWidth, vChar cFill, 
									   std::ios::fmtflags flags) {
		vStringStream stream;

		stream.width(usWidth);
		stream.fill(cFill);

		if (flags) {
			stream.setf(flags);
		}
		stream<<iVal;

		return vString(stream.str());
	}

	vString vStringConverter::ToString(vUInt uiVal, vUShort usWidth, vChar cFill, 
									   std::ios::fmtflags flags) {
		vStringStream stream;

		stream.width(usWidth);
		stream.fill(cFill);

		if (flags) {
			stream.setf(flags);
		}
		stream<<uiVal;

		return vString(stream.str());
	}

	vString vStringConverter::ToString(vLong lVal, vUShort usWidth, vChar cFill, 
									   std::ios::fmtflags flags) {
		vStringStream stream;

		stream.width(usWidth);
		stream.fill(cFill);

		if (flags) {
			stream.setf(flags);
		}
		stream<<lVal;

		return vString(stream.str());
	}

	vString vStringConverter::ToString(vUInt32 ulVal, vUShort usWidth, vChar cFill, 
									   std::ios::fmtflags flags) {
		vStringStream stream;

		stream.width(usWidth);
		stream.fill(cFill);

		if (flags) {
			stream.setf(flags);
		}
		stream<<ulVal;

		return vString(stream.str());
	}

	vString vStringConverter::ToString(vBool bVal, vStringConverter::eBoolType eWriteType) {
		switch (eWriteType) {
			case vStringConverter::VBT_TRUEFALSE_C:
			default:
				return (bVal ? "True" : "False");
			case vStringConverter::VBT_TRUEFALSE_U:
				return (bVal ? "TRUE" : "FALSE");
			case vStringConverter::VBT_TRUEFALSE_L:
				return (bVal ? "true" : "false");
			case vStringConverter::VBT_YESNO_C:
				return (bVal ? "Yes" : "No");
			case vStringConverter::VBT_YESNO_U:
				return (bVal ? "YES" : "NO");
			case vStringConverter::VBT_YESNO_L:
				return (bVal ? "yes" : "no");
			case vStringConverter::VBT_ONEZERO:
				return (bVal ? "1" : "0");
		}
	}

	vString vStringConverter::ToString(vColor color, vStringConverter::eColorType colorType) {
		vStringStream ss;
		vString delim;
		
		switch (colorType) {			
			case vStringConverter::VCT_COMMA:
			default:
				delim = ",";
				break;
			case vStringConverter::VCT_SPACE:
				delim = " ";
				break;
			case vStringConverter::VCT_SEMICOLON:
				delim = ";";
				break;
		}

		ss<<"("<<color.R<<delim<<" "<<color.G<<delim<<" "<<color.B<<delim<<" "<<color.A<<")";
		
		return vString(ss.str());
	}

	vInt vStringConverter::ToInt(const vString& str, vBool *bResultOk) {
		std::istringstream ss(str.ToStdString());
		vInt d;

		ss>>d;
		if(!(ss && (ss >> std::ws).eof())) {
			*bResultOk = false;

			return 0;
		}

		*bResultOk = true;	

		return d;
	}

	vUInt vStringConverter::ToUInt(const vString& str, vBool *bResultOk) {
		std::istringstream ss(str.ToStdString());
		vUInt d;

		ss>>d;
		if(!(ss && (ss >> std::ws).eof())) {
			*bResultOk = false;

			return 0;
		}

		*bResultOk = true;	

		return d;
	}

	vLong vStringConverter::ToLong(const vString& str, vBool *bResultOk) {
		std::istringstream ss(str.ToStdString());
		vLong d;

		ss>>d;
		if(!(ss && (ss >> std::ws).eof())) {
			*bResultOk = false;

			return 0;
		}

		*bResultOk = true;	

		return d;
	}

	vUInt32 vStringConverter::ToUInt32(const vString& str, vBool *bResultOk) {
		std::istringstream ss(str.ToStdString());
		vUInt32 d;

		ss>>d;
		if(!(ss && (ss >> std::ws).eof())) {
			*bResultOk = false;

			return 0;
		}

		*bResultOk = true;	

		return d;
	}

	vReal vStringConverter::ToReal(const vString& str, vBool *bResultOk) {
		std::istringstream ss(str.ToStdString());
		vReal d;

		ss>>d;
		if(!(ss && (ss >> std::ws).eof())) {
			*bResultOk = false;

			return static_cast<vReal>(0);
		}

		*bResultOk = true;	

		return d;
	}

	vBool vStringConverter::ToBool(const vString& str, vBool *bResultOk) {
		vString strLower(str.ToConstCharPtr());
		strLower = strLower.ToLowerCase();

		if (strLower.IsEqual("true") || strLower.IsEqual("yes") || strLower.IsEqual("1")) {
			*bResultOk = true;

			return true;
		} else if (strLower.IsEqual("false") || strLower.IsEqual("no") || strLower.IsEqual("0")) {
			*bResultOk = true;

			return false;
		}
		
		*bResultOk = false;

		return false;
	}

	vColor vStringConverter::ToColor(const vString& str, vBool *bResultOk) {
		vArray<vString> params;
		vString delims[3] = {";", ",", " "};
		vReal vR, vB, vG, vA;
		vBool bOk = false;
		vUInt uiIndex = 0;

		try {
			while(uiIndex < 3) {
				params = vStringTokenizer::Split(str, delims[uiIndex]);
				vA = 1.0;
				if (params.Size() >= 3) {
					vR = vStringConverter::ToReal(vStringTokenizer::EraseDelimeter(params[0], " "), &bOk);
					if (!bOk) {
						throw;
					}
					vG = vStringConverter::ToReal(vStringTokenizer::EraseDelimeter(params[1], " "), &bOk);
					if (!bOk) {
						throw;
					}
					vB = vStringConverter::ToReal(vStringTokenizer::EraseDelimeter(params[2], " "), &bOk);
					if (!bOk) {
						throw;
					}
					if (params.Size() == 4) {
						vA = vStringConverter::ToReal(vStringTokenizer::EraseDelimeter(params[3], " "), &bOk);
						if (!bOk) {
							throw;
						}
					}
					*bResultOk = true;

					return vColor(vR, vG, vB, vA);
				}
				uiIndex++;
			}
		} catch (...) {
			*bResultOk = false;
			
			return vColor::Black;
		}
		
		*bResultOk = false;

		return vColor::Black;
	}
}